package cn.bugstack.openai.executor.model.chatgpt.valobj;

import cn.bugstack.openai.executor.parameter.Functions;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * 对话聊天，请求信息依照；OpenAI官网API构建参数；https://platform.openai.com/playground
 *
 * @author 小傅哥，微信：fustack
 */
@Data
@Slf4j
@JsonInclude(JsonInclude.Include.NON_NULL)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ChatGPTCompletionRequest implements Serializable {

    /**
     * 默认模型
     */
    @Builder.Default
    private String model = Model.GPT_3_5_TURBO.getCode();
    /**
     * 问题描述
     */
    private List<Message> messages;
    /**
     * 函数列表
     */
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private List<Functions> functions;
    /**
     * 控制模型如何响应函数调用。
     * "none"表示模型不调用函数，而是响应最终用户。
     * "auto"表示模型可以在最终用户和调用函数之间选择。
     * 通过{"name": "my_function"}指定特定函数会强制模型调用该函数。当没有函数时，默认为"none"。当存在函数时，默认为"auto"。
     */
    @JsonProperty("function_call")
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private String functionCall;
    /**
     * 控制温度【随机性】；0到2之间。较高的值(如0.8)将使输出更加随机，而较低的值(如0.2)将使输出更加集中和确定
     * 一般建议只更改此参数或top_p参数中的一个
     */
    @Builder.Default
    private float temperature = 0.2f;
    /**
     * 多样性控制；使用温度采样的替代方法称为核心采样，其中模型考虑具有top_p概率质量的令牌的结果。因此，0.1 意味着只考虑包含前 10% 概率质量的代币
     */
    @JsonProperty("top_p")
    @Builder.Default
    private float topP = 1f;
    /**
     * 为每个提示生成的完成次数
     */
    @Builder.Default
    private Integer n = 1;
    /**
     * 是否为流式输出；就是一蹦一蹦的，出来结果
     */
    @Builder.Default
    private boolean stream = false;
    /**
     * 停止输出标识
     */
    private List<String> stop;
    /**
     * 输出字符串限制；0 ~ 4096
     */
    @JsonProperty("max_tokens")
    @Builder.Default
    private Integer maxTokens = 2048;
    /**
     * 频率惩罚；降低模型重复同一行的可能性
     */
    @JsonProperty("frequency_penalty")
    @Builder.Default
    private double frequencyPenalty = 0;
    /**
     * 存在惩罚；增强模型谈论新话题的可能性
     */
    @JsonProperty("presence_penalty")
    @Builder.Default
    private double presencePenalty = 0;
    /**
     * 生成多个调用结果，只显示最佳的。这样会更多的消耗你的 api token
     */
    @JsonProperty("logit_bias")
    private Map logitBias;
    /**
     * 调用标识，避免重复调用
     */
    private String user;

    @Getter
    @AllArgsConstructor
    public enum Role {

        SYSTEM("system"),
        USER("user"),
        ASSISTANT("assistant"),;

        private final String code;

    }

    @Getter
    @AllArgsConstructor
    public enum Model {
        /**
         * gpt-3.5-turbo
         */
        GPT_3_5_TURBO("gpt-3.5-turbo"),
        GPT_3_5_TURBO_1106("gpt-3.5-turbo-1106"),
        /**
         * gpt-3.5-turbo-16k
         */
        GPT_3_5_TURBO_16K("gpt-3.5-turbo-16k"),
        /**
         * GPT4.0
         */
        GPT_4("gpt-4"),
        /**
         * GPT4.0 超长上下文
         */
        GPT_4_32K("gpt-4-32k"),
        DALL_E_2("dall-e-2"),
        DALL_E_3("dall-e-3"),
        ;
        private final String code;
    }

}
